package org.correct.index;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Iterator;


import org.correct.config.*;
import org.correct.parser.Parser;

public class IndexWriter extends Thread{
	HashMap<String, Integer> table;
	int doc;
	int termNum;
	static String dic = "";
	static int dicNum = 0;
	static int dicFile = 0;
	static int docNum = 0;
	
	public IndexWriter(HashMap<String, Integer> table, int doc, int termNum){
		this.table = table;
		this.doc = doc;
		this.termNum = termNum;
	}
	
	public void run(){
		try{
			IndexParser.lock = true;
			//System.out.println(doc);
			Iterator<String> iterator = table.keySet().iterator();
			//System.out.println("Writing index #" + doc);
			while(iterator.hasNext()){				
				String str = iterator.next();
				int value = str.hashCode() % 1000000;
				int acc = 0;
				while(true){
					File file;
					if(acc == 0){
						file = new File(Config.INDEX_PATH + Math.abs(value) / Config.TERM_PER_FILE);
					}else{
						file = new File(Config.INDEX_PATH + Math.abs(value) / Config.TERM_PER_FILE + "_" + acc);
					}
					if(!file.exists()){
						file.createNewFile();
					}
					FileInputStream fis = new FileInputStream(file);
					BufferedReader br = new BufferedReader(new InputStreamReader(fis));				
					int i;
					StringBuffer tmp = new StringBuffer("");
					int k = (value > 0) ? value % Config.TERM_PER_FILE : (value % Config.TERM_PER_FILE + 100);
					for(i = 0; i < k; i++){
						String s = br.readLine();
						if(s != null){
							tmp = tmp.append(s);
						}
						tmp.append("\n");
					}
					String s = br.readLine();					
					if(s == null || s.equals("")){						
						tmp = tmp.append(str + " " + doc + ":" + 1.0 * table.get(str) / termNum + "\n");
						dic = dic.concat(str + " 0\n");
						dicNum++;
						if(dicNum == 1000){
							writeDic();
						}
					}else{
						String[] strs = s.split(" ");
						if(strs[0].equals(str)){
							tmp.append(s);
							tmp = tmp.append(" " + doc + ":" + 1.0 * table.get(str) / termNum + "\n");
						}else{
							acc++;
							br.close();
							fis.close();
							continue;
						}
					}		
					s = br.readLine();
					while(s != null){
						tmp = tmp.append(s + "\n");
						s = br.readLine();
					}
					br.close();
					fis.close();
					FileOutputStream fos = new FileOutputStream(file);
					BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
					bw.write(tmp.toString());				
					bw.close();				
					fos.close();
					break;
				}					
			}
			IndexParser.lock = false;
			docNum++;
			if(docNum == Parser.docNum){
				//PageInfoAccessor pageInfo = new PageInfoAccessor(Config.PAGE_INFO_PATH);
				//pageInfo.load();
				//pageInfo.updateInfo(PageInfoItem.InfoType.termCount, IndexParser.termCountMap);
				//pageInfo.savePageInfo();
				writeDic();
				updateIndex();				
			}			
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("写" + doc + "索引失败");
			IndexParser.lock = false;
			docNum++;
		}
	}
	
	void writeDic(){
		File file = new File(Config.DIC_PATH + "_" + dicFile);
		try{
			file.createNewFile();
			FileOutputStream fos = new FileOutputStream(file);
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
			bw.write(dic);
			bw.close();
			fos.close();
			dicNum = 0;
			dicFile++;
			dic = "";
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("写词典错误");
		}
	}
	
	public static void updateIndex(){
		try{
			while(IndexParser.lock){
				sleep(100);
			}
		}catch(Exception e){
			
		}
		System.out.println("Updating weight...");
		File index = new File(Config.INDEX_DIR);
		File[] indexs = index.listFiles();
		for(int i = 0; i < indexs.length; i++){
			File file = indexs[i];
			try{
				FileInputStream fis = new FileInputStream(file);
				BufferedReader br = new BufferedReader(new InputStreamReader(fis));
				StringBuffer str = new StringBuffer("");
				for(String line = br.readLine(); line != null; line = br.readLine()){
					if(line.equals("")){
						str = str.append("\n");
						continue;
					}
					String[] docEntry = line.split(" ");
					str = str.append(docEntry[0]);
					int n = docEntry.length - 1;
					for(int j = 1; j < docEntry.length; j++){
						String[] termElem = docEntry[j].split(":");
						str = str.append(" " + termElem[0] + ":");
						double weight = Double.parseDouble(termElem[1]);
						weight *= Math.log(docNum / n) + 1;
						str = str.append(weight);
					}
					str = str.append("\n");
				}
				br.close();
				fis.close();
				FileOutputStream fos = new FileOutputStream(file);
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
				bw.write(str.toString());				
				bw.close();				
				fos.close();
			}catch(Exception e){
				e.printStackTrace();
				System.out.println("更新索引" + i + "权重错误");
			}
		}
	}
}
